在 python 开发时,我比较喜欢的做法是在.py文件中写函数,然后开一个相应的test.ipynb notebook 调试。例如:
py
# foo.py
def foo():
msg = 'Hi'
# msg = 'Hello'
return msgpy
# test.ipynb
# cell1
%load_ext autoreload
%autoreload 2
# cell2
from foo import foo
# cell3
foo()这样一旦根据 notebook 中的调试结果在 foo.py 对函数进行改动,就可以实时反馈继续调试。
不过这个 autoreload 的功能仅仅局限于追踪类和函数的改动,比如以下逻辑:
py
# foo.py
foo = 'Hi'
# foo = 'Hello'这种情况下,切换两行注释后,如果仅仅运行 cell3 并不能改变在 notebook 中导入的 foo 值。如果运行 cell2 重新导入 foo,就可以更新了。
但更隐蔽的坑在于如果简单的调整一下上述逻辑,把它变成
py
# foo.py
from bar import bar
foo = bar()py
# bar.py
def bar():
msg = 'Hi'
# msg = 'Hello'
return msg此时如果在bar.py中切换两行注释,即便重新运行 cell2 重新导入foo,也不会改变 foo 的值。
是不是有点意外?我今天写的代码就掉进了这个坑。目前我觉得规避这个问题的方法是在使用 autoreload 的特性时不要引入一个变量,总是先引入函数再赋值就可以确保函数是更新的。